package service;

import model.Paper;
import model.PaperType;
import model.Student;
import service.exception.NoEnoughPapersException;
import service.strategy.PaperSelectionStrategy;
import service.strategy.RandomSelectionStrategy;

import java.util.*;

public class PaperList {
    private final String teacher;
    private final List<Paper> papers;
    private final PaperSelection selections = new PaperSelection();
    private PaperSelectionStrategy selectionStrategy = new RandomSelectionStrategy();
    
    public PaperList(String teacher, List<Paper> papers) {
        this.teacher = teacher;
        this.papers = new ArrayList<>(papers); // 防御性复制
    }
    
    public void setSelectionStrategy(PaperSelectionStrategy strategy) {
        this.selectionStrategy = strategy;
    }
    
    private List<Paper> getUnselectedPapersByType(PaperType type) {
        List<Paper> results = new ArrayList<>();
        for (Paper p : this.papers) {
            if (!selections.isSelected(p)) {
                if (type == PaperType.Any || 
                    type.toString().equals(p.getClass().getSimpleName())) {
                    results.add(p);
                }
            }
        }
        return Collections.unmodifiableList(results);
    }
    
    public List<Paper> selectPaperByRandom(Student student) 
        throws NoEnoughPapersException {
        
        // 参数校验
        validateStudent(student);
        
        // 状态校验（防止重复选择）
        if (selections.isStudentAlreadySelected(student)) {
            throw new IllegalStateException("学生 " + student.getName() + " 已选择过论文");
        }
        
        // 获取可用论文
        List<Paper> availablePapers = 
            getUnselectedPapersByType(student.getPreferredPaperType());
        
        int availableCount = availablePapers.size();
        int requiredCount = student.getPreferredQuantity();
        
        // 检查论文数量是否足够
        if (availableCount < requiredCount) {
            throw new NoEnoughPapersException(
                "学生 " + student.getName() + 
                " 希望选论文 " + requiredCount + " 篇，" +
                "但目前只有 " + availableCount + " 篇可选"
            );
        }
        
        // 使用策略选择论文
        List<Paper> selected = selectionStrategy.selectPapers(availablePapers, requiredCount);
        
        // 记录选择结果
        for (Paper paper : selected) {
            selections.addSelection(student, paper);
        }
        return selected;
    }
    
    private void validateStudent(Student student) {
        if (student == null) {
            throw new IllegalArgumentException("学生对象不可为null");
        }
        if (student.getPreferredQuantity() <= 0) {
            throw new IllegalArgumentException("学生期望数量必须大于0");
        }
        if (student.getPreferredPaperType() == null) {
            throw new IllegalArgumentException("学生偏好类型不可为null");
        }
    }
    
    public PaperSelection getSelectionResult() {
        return selections;
    }
    
    public boolean isStudentAlreadySelected(Student student) {
        return selections.isStudentAlreadySelected(student);
    }
}